package view.micro
{
	import adobe.utils.ProductManager;
	import events.GuiEvent;
	import flash.display.Stage;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import util.MyMath;
	import util.Settings;
	
	/**
	 */
	public class Camera
	{
		private var stage:Stage;
		private var _x:Number;
		private var _y:Number;
		private var z:Number;
		private var _tx:Number;
		private var ty:Number;
		private var tz:Number;
		static private const SCROLL_SPEED:Number = 0.4;
		
		public function Camera(stage:Stage)
		{
			this.stage = stage;
			
			x = 0;
			tx = x;
			y = 0;
			ty = y;
			z = 0.0;
			tz = z;
		}
		
		/**
		 * Called every frame.
		 */
		public function update():void
		{
			z = (SCROLL_SPEED) * tz + (1.0 - SCROLL_SPEED) * z;
			x = (SCROLL_SPEED) * tx + (1.0 - SCROLL_SPEED) * x;
			y = (SCROLL_SPEED) * ty + (1.0 - SCROLL_SPEED) * y;
		}
		
		/**
		 * Zoom in or out.
		 * @param	dz
		 */
		public function zoom(dz:Number):void
		{
			tz += dz;
		}
		
		/**
		 * Zoom to a specific level.
		 * @param	tz
		 */
		public function zoomTo(dz:Number):void
		{
			z = dz;
			tz = z;
		}
		
		/**
		 * Scroll the camera by a specific amount.
		 * @param	dx
		 * @param	dy
		 */
		public function scroll(dx:Number, dy:Number):void
		{
			x += dx;
			tx = x;
			y += dy;
			ty = y;
		}
		
		/**
		 * Scroll the camera to a specific location. Centers it it center is true;
		 * @param	tx
		 * @param	ty
		 * @param	center
		 */
		public function scrollTo(dx:Number, dy:Number, center:Boolean):void
		{
			trace("Scroll To:" + dx + "," + dy);
			tx = dx;
			ty = dy;
		}
		
		/**
		 * The x position the sprite should be set to.
		 */
		public function get sprite_x():Number
		{
			return sprite_position.x;
		}
		
		/**
		 * The y position the sprite should be set to.
		 */
		public function get sprite_y():Number
		{
			return sprite_position.y;
		}
		
		public function get sprite_position():Point
		{
			var m:Matrix = new Matrix();
			m.translate(x - width / 2, y - height / 2);
			m.scale(sprite_scale, sprite_scale);
			var result:Point = m.transformPoint(new Point());
			result.x *= -1;
			result.y += stage.stageHeight;
			return result;
		}
		
		/**
		 * The scale the sprite should be set to.
		 */
		public function get sprite_scale():Number
		{
			return Math.pow(2, z);
		}
		
		/**
		 * Viewport width in world size.
		 */
		private function get width():Number
		{
			return stage.stageWidth / sprite_scale;
		}
		
		/**
		 * Viewport height in world size.
		 */
		private function get height():Number
		{
			return stage.stageHeight / sprite_scale;
		}
		
		public function get tx():Number
		{
			return _tx;
		}
		
		public function set tx(value:Number):void
		{
			if (value < width / 2)
				value = width / 2;
			_tx = value;
		}
		
		public function get x():Number
		{
			return _x;
		}
		
		public function set x(value:Number):void
		{
			if (value < width / 2)
				value = width / 2;
			_x = value;
		}
		
		public function get y():Number 
		{
			return _y;
		}
		
		public function set y(value:Number):void 
		{
			if (value < height / 2)
				value = height / 2;
			_y = value;
		}
	}

}